package com.rtx.wms.std.asn.service.impl;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import com.rtx.wms.std.asn.mapper.dymapper.DyReceiptMapper;
import com.rtx.wms.std.asn.mapper.dymapper.DyReceiptdetailMapper;
import com.rtx.wms.std.ctclass.ClassHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rtx.api.annotation.DataSourceAnnotation;
import com.rtx.edi.model.api.bo.ApiMappingInfoBo;
import com.rtx.wms.std.asn.bean.ApiReceipt;
import com.rtx.wms.std.asn.bean.Receipt;
import com.rtx.wms.std.asn.bean.Receiptdetail;
import com.rtx.wms.std.asn.bean.RtxOnescanreturngoods;
import com.rtx.wms.std.asn.mapper.ApiReceiptMapper;
import com.rtx.wms.std.asn.mapper.ReceiptMapper;
import com.rtx.wms.std.asn.mapper.ReceiptdetailMapper;
import com.rtx.wms.std.asn.mapper.RtxOnescanreturngoodsMapper;
import com.rtx.wms.std.asn.service.ApiReceiptService;
import com.rtx.wms.std.asn.service.ReceiptService;
import com.rtx.wms.std.so.bean.ApiCancle;
import com.rtx.wms.std.so.mapper.ApiCancleMapper;

@Service
public class ReceiptServiceImpl implements ReceiptService {

    @Autowired
    private ReceiptMapper receiptMapper;

    @Autowired
    private ReceiptdetailMapper receiptdetailMapper;
    
    @Autowired
    ApiReceiptService apiReceiptService;
    
    @Autowired
    ApiReceiptMapper apiReceiptMapper;
    
    @Autowired
    RtxOnescanreturngoodsMapper rtxOnescanreturngoodsMapper;
    
    @Autowired
    ApiCancleMapper apiCancleMapper;

	@Autowired
	private DyReceiptMapper dyReceiptMapper;

	@Autowired
	private DyReceiptdetailMapper dyReceiptdetailMapper;

    @DataSourceAnnotation
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addReceipt(String whseid, Receipt receipt,ApiMappingInfoBo bo) {
    	LambdaQueryWrapper<ApiReceipt> query = Wrappers.lambdaQuery();
    	query.eq(ApiReceipt::getExternreceiptkey, receipt.getExternreceiptkey());
    	query.eq(ApiReceipt::getEdiflag,"PC");
    	boolean cancle = apiReceiptMapper.exists(query);
    	if(cancle) {
    		receipt.setStatus("20");
    		receipt.getDetails().forEach(entity->entity.setStatus("20"));
    	}
		//是否使用 动态加载字段拼接sql
		boolean activeConfig = false;
		try {
			//获取生效的目标apiid，就是当前需要被调用的restapi
			Long targetid = bo.getTargetApi().getId();
			//获取启动或者被被更新时候动态创建的实体类
			Map<String,Class> map = ClassHolder.apiconfigClassMap.get(targetid+"");
			//假如动态创建的类存在则 通过调用通过反射获取bean对象属性拼接sql的方法
			if(map != null) {
				activeConfig = true;
			}
		} catch (Exception e) {
		}
		if(activeConfig){
			dyReceiptMapper.rtxconfigColumnsSave(receipt);
			for(Receiptdetail od : receipt.getDetails()){
				dyReceiptdetailMapper.rtxconfigColumnsSave(od);
			}
		}else{
			receiptMapper.insert(receipt);
			for(Receiptdetail od : receipt.getDetails()){
				receiptdetailMapper.insert(od);
			}
		}
    }

    @DataSourceAnnotation
    @Override
    public List<Receipt> selectReceiptByWrapper(String whseid, Wrapper<Receipt> wrapper) {
        List<Receipt> orderList = receiptMapper.selectList(wrapper);
        for(Receipt o : orderList){
            LambdaQueryWrapper<Receiptdetail> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper
            .eq(Receiptdetail::getReceiptkey,o.getReceiptkey())
            .gt(Receiptdetail::getQtyreceived, "0");
            o.setDetails(receiptdetailMapper.selectList(queryWrapper));
        }
        return orderList;
    }
    
    @DataSourceAnnotation
    @Override
    public void updateByWrapper(String whseid, LambdaUpdateWrapper<Receipt> wrapper) {
        receiptMapper.update(null,wrapper);
    }

    @DataSourceAnnotation
	@Override
	public void handlerExistsReceipt(String whseid, String externreceiptkey) {
    	//根据“外部单号”查询RECEIPT表中是否存在，如果没有就新建一个WMS入库单。
        LambdaQueryWrapper<Receipt> receiptQuery = Wrappers.lambdaQuery();
        receiptQuery.eq(Receipt::getExternreceiptkey,externreceiptkey);
        List<Receipt> receiptList = receiptMapper.selectList(receiptQuery);
        if(!CollectionUtils.isEmpty(receiptList)){
        	//否则查看WMS订单状态是否是初始状态（RECEIPT单状态STATUS<5）
        	Receipt receipt = receiptList.get(0);
        	
            LambdaQueryWrapper<Receiptdetail> receiptdetailQuery = Wrappers.lambdaQuery();
            receiptdetailQuery.eq(Receiptdetail::getExternreceiptkey,externreceiptkey);
            receiptdetailQuery.gt(Receiptdetail::getQtyreceived, 0);
            boolean gt0columns = receiptdetailMapper.exists(receiptdetailQuery);
            if(gt0columns) {
            	throw new RuntimeException("入库单：" + receipt.getExternreceiptkey() +"已开始收货");
            }
            //判断在扫描表是否存在
            LambdaQueryWrapper<RtxOnescanreturngoods> rtxOnescanreturngoodsQuery = Wrappers.lambdaQuery();
            rtxOnescanreturngoodsQuery.eq(RtxOnescanreturngoods::getExternreceiptkey, externreceiptkey);
            boolean rtxOnescanreturngoodsExists = rtxOnescanreturngoodsMapper.exists(rtxOnescanreturngoodsQuery);
            if(rtxOnescanreturngoodsExists) {
            	throw new RuntimeException("入库单：" + receipt.getExternreceiptkey() +"已开始收货");
            }
            //如果否，则将WMS表头和表明细全部删除后，再插入一个新的WMS入库单；
            //如果是,写入“XXX单据已开始收货”报错数据到ERRMSG中，不允许改单。
            if(Integer.parseInt(receipt.getStatus()) > 4){
                throw new RuntimeException("入库单：" + receipt.getExternreceiptkey() +"已开始收货");
            }else{
                //根据外部单号删除明细
                LambdaQueryWrapper<Receiptdetail> detailQuery = Wrappers.lambdaQuery();
                detailQuery.eq(Receiptdetail::getExternreceiptkey,externreceiptkey);
                receiptdetailMapper.delete(detailQuery);
                //删除表头
                receiptMapper.delete(receiptQuery);
            }
        }
	}
    
	@DataSourceAnnotation
    @Override
    public void receiptCancel(String whseid, String externreceiptkey) {
		
        LambdaQueryWrapper<ApiReceipt> rquery = Wrappers.lambdaQuery();
        rquery.eq(ApiReceipt::getExternreceiptkey, externreceiptkey);
        List<ApiReceipt> rList = apiReceiptMapper.selectList(rquery);
    	String P_Status = "";
		String PS_Status = "";
		String PF_Status = "";
		String PC_Status = "";
		
		for(ApiReceipt r:rList) {
			if("PS".equals(r.getEdiflag())) {
				PS_Status ="true";
			}
			if("PF".equals(r.getEdiflag())) {
				PF_Status ="true";
			}
			if("P".equals(r.getEdiflag())) {
				P_Status ="true";
			}
			if("PC".equals(r.getEdiflag())) {
				PC_Status ="true";
			}
		}
		
		if("true".equals(PC_Status)) {
    		return;
    	}else if("true".equals(P_Status) || "true".equals(PF_Status)) {
    		LambdaUpdateWrapper<ApiReceipt> apiOrdersUpd = Wrappers.lambdaUpdate();
    		apiOrdersUpd.eq(ApiReceipt::getExternreceiptkey,externreceiptkey);
    		apiOrdersUpd.set(ApiReceipt::getEdiflag, "PC");
    		apiOrdersUpd.set(ApiReceipt::getEditdate, LocalDateTime.now());
    		apiReceiptMapper.update(null, apiOrdersUpd);
    		ApiCancle apicancle = new ApiCancle();
    		apicancle.setType("asn");
    		apicancle.setExternkey(externreceiptkey);
    		apicancle.setEdiflag("P");
    		apiCancleMapper.insert(apicancle);
		}else if("true".equals(PS_Status)) {
	        //【收货单取消逻辑】根据“外部单号”查询RECEIPT表中是否存在
	        //不存在，接口返回MESSAGE错误信息“XX单号不存在”，返回状态FLAG为failure
	        //存在：
	        //当RECEIPT表单据状态>“4收货中”<“20已取消”，则接口返回MESSAGE错误信息“XX单号已收货”，返回状态FLAG为failure
	        //当RECEIPT表单据状态<“4收货中”，订单取消标记更新为“20已取消”，返回状态FLAG为success成功。
	        LambdaQueryWrapper<Receipt> query = Wrappers.lambdaQuery();
	        query.eq(Receipt::getExternreceiptkey,externreceiptkey);
	        List<Receipt> receiptList = receiptMapper.selectList(query);
	        Assert.notEmpty(receiptList,"入库单：" + externreceiptkey + "不存在");
	        Receipt receipt = receiptList.get(0);
	        int status = Integer.parseInt(receipt.getStatus());
	        if(status > 4 && status < 20){
	            throw new RuntimeException("入库单：" + externreceiptkey + "已收货");
	        }else{
	            if(status != 20){
	                LambdaUpdateWrapper<Receipt> update = Wrappers.lambdaUpdate();
	                update.eq(Receipt::getExternreceiptkey,externreceiptkey).set(Receipt::getStatus,"20");
	                receiptMapper.update(null,update);
	            }
	        }
		}else {
			throw new RuntimeException("取消失败-请联系技术支持");
		}

    }

	@DataSourceAnnotation
	@Override
	public List<Receiptdetail> selectReceiptDetailByWrapper(String whseid, Wrapper<Receiptdetail> wrapper) {
		return receiptdetailMapper.selectList(wrapper);
	}

	@DataSourceAnnotation
	@Override
	public String selectReceiptStatusByWrapper(String whseid, String receiptkey) {
        LambdaQueryWrapper<Receipt> receiptQuery = Wrappers.lambdaQuery();
        receiptQuery.eq(Receipt::getReceiptkey,receiptkey);
        List<Receipt> list =  receiptMapper.selectList(receiptQuery);
		return list.get(0).getStatus();
	}
	
    @Transactional
    @DataSourceAnnotation
    @Override
    public void updateDetailStatusByWrapper(String whseid, Receipt r) {
    	for(Receiptdetail rd:r.getDetails()) {
    		LambdaUpdateWrapper<Receiptdetail> wrapper = Wrappers.lambdaUpdate();
    		wrapper.eq(Receiptdetail::getSerialkey,rd.getSerialkey())
    		.set(Receiptdetail::getRtxeditflagErp,rd.getRtxeditflagErp())
    		.set(Receiptdetail::getRtxeditmsgErp,r.getEdimsg());
    		receiptdetailMapper.update(null, wrapper);
    	}
    }
}
